using MicroMsg.Common.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace MicroMsg.Storage
{
	public class StorageKeyValue : IStorageFlush
	{
		private const string TAG = "StorageKeyValue";
		private Dictionary<Type, object> mapConfig = new Dictionary<Type, object>();
		private int modify;
		private object objLock = new object();
		private Func<string> getPath;
		private Dictionary<Type, Action> mapDelayWriteAction = new Dictionary<Type, Action>();
		public StorageKeyValue(Func<string> func_0)
		{
			this.getPath = func_0;
			StorageBasic.registerFlushNotify(this);
		}
		public void onFlush()
		{
			lock (this.objLock)
			{
				if (this.mapDelayWriteAction.get_Count() > 0)
				{
					using (Dictionary<Type, Action>.Enumerator enumerator = this.mapDelayWriteAction.GetEnumerator())
					{
						while (enumerator.MoveNext())
						{
							KeyValuePair<Type, Action> current = enumerator.get_Current();
							current.get_Value().Invoke();
						}
					}
					this.mapDelayWriteAction.Clear();
				}
			}
			if (this.modify > 0)
			{
				Log.smethod_5("StorageKeyValue", string.Concat(new object[]
				{
					"save ",
					this.modify,
					" modify to path=",
					this.getPath.Invoke()
				}));
				this.modify = 0;
				this.save<CommanConfig>(false);
			}
		}
		private string getFilePath<T>()
		{
			return this.getPath.Invoke() + "/" + typeof(T).get_Name() + ".xml";
		}
		public T method_0<T>() where T : class
		{
			T result;
			lock (this.objLock)
			{
				if (this.mapConfig.ContainsKey(typeof(T)))
				{
					result = (this.mapConfig.get_Item(typeof(T)) as T);
				}
				else
				{
					T t = this.read<T>();
					Log.smethod_5("StorageKeyValue", "read class=" + typeof(T).get_Name());
					if (t == null)
					{
						t = (Activator.CreateInstance(typeof(T)) as T);
						if (t == null)
						{
							DebugEx.debugBreak();
						}
					}
					this.mapConfig.set_Item(typeof(T), t);
					result = t;
				}
			}
			return result;
		}
		public bool save<T>(bool removeCache = false) where T : class
		{
			bool result;
			lock (this.objLock)
			{
				if (!this.mapConfig.ContainsKey(typeof(T)))
				{
					result = false;
				}
				else
				{
					if (!StorageXml.saveObject<T>(this.mapConfig.get_Item(typeof(T)) as T, this.getFilePath<T>()))
					{
						DebugEx.debugBreak();
					}
					if (removeCache)
					{
						this.mapConfig.Remove(typeof(T));
					}
					result = true;
				}
			}
			return result;
		}
		public void releaseAll(bool bFlush = true)
		{
			if (bFlush)
			{
				this.onFlush();
			}
			lock (this.objLock)
			{
				this.mapConfig.Clear();
			}
		}
		public void checkEmpty()
		{
			lock (this.objLock)
			{
				if (this.mapConfig.get_Count() > 0)
				{
					DebugEx.debugBreak();
				}
			}
		}
		public void delete<T>()
		{
			lock (this.objLock)
			{
				if (this.mapConfig.ContainsKey(typeof(T)))
				{
					this.mapConfig.Remove(typeof(T));
				}
				StorageIO.deleteFile(this.getFilePath<T>());
			}
		}
		public T read<T>() where T : class
		{
			T result;
			lock (this.objLock)
			{
				result = StorageXml.loadObject<T>(this.getFilePath<T>());
			}
			return result;
		}
		public bool write<T>(T data) where T : class
		{
			bool result;
			lock (this.objLock)
			{
				result = StorageXml.saveObject<T>(data, this.getFilePath<T>());
			}
			return result;
		}
		public bool delayWrite<T>(T data) where T : class
		{
			lock (this.objLock)
			{
				this.mapDelayWriteAction.set_Item(typeof(T), delegate
				{
					this.write<T>(data);
				});
			}
			return true;
		}
		public bool exist<T>()
		{
			return StorageIO.fileExists(this.getFilePath<T>());
		}
		public T getValue<T>(string key_name, T def_value)
		{
			if (string.IsNullOrEmpty(key_name))
			{
				return def_value;
			}
			CommanConfig commanConfig = this.method_0<CommanConfig>();
			T result;
			lock (this.objLock)
			{
				if (commanConfig.mapValue.ContainsKey(key_name))
				{
					try
					{
						result = (T)((object)commanConfig.mapValue.get_Item(key_name));
						return result;
					}
					catch (Exception exception_)
					{
						Log.smethod_2("StorageKeyValue", "get value type error ", exception_);
						result = def_value;
						return result;
					}
				}
				result = def_value;
			}
			return result;
		}
		public bool setValue<T>(string key_name, T value)
		{
			if (string.IsNullOrEmpty(key_name))
			{
				return false;
			}
			if (typeof(T) == typeof(string) && !StorageKeyValue.validString(value as string))
			{
				DebugEx.debugBreak();
				return false;
			}
			CommanConfig commanConfig = this.method_0<CommanConfig>();
			lock (this.objLock)
			{
				commanConfig.mapValue.set_Item(key_name, value);
				this.modify++;
			}
			if (Debugger.get_IsAttached())
			{
				this.onFlush();
			}
			return true;
		}
		public bool delValue(string key_name)
		{
			if (string.IsNullOrEmpty(key_name))
			{
				return false;
			}
			CommanConfig commanConfig = this.method_0<CommanConfig>();
			bool result;
			lock (this.objLock)
			{
				if (!commanConfig.mapValue.ContainsKey(key_name))
				{
					result = false;
				}
				else
				{
					commanConfig.mapValue.Remove(key_name);
					this.modify++;
					result = true;
				}
			}
			return result;
		}
		public static bool validString(string string_0)
		{
			if (string_0 == null)
			{
				return false;
			}
			for (int i = 0; i < string_0.get_Length(); i++)
			{
				char c = string_0.get_Chars(i);
				if ((c >= '\0' && c <= '\b') || (c >= '\v' && c <= '\f') || (c >= '\u000e' && c <= '\u001f'))
				{
					return false;
				}
			}
			return true;
		}
	}
}
